#ifndef __ELF_H__
#define __ELF_H__

#include "types.h"

#if defined(__GNUC__)
#define	__PACKED__	__attribute__((packed))
#else
#define	__PACKED__		/* nothing */
#endif

#define ET_NONE		0
#define ET_REL		1
#define ET_EXEC		2
#define ET_DYN		3
#define ET_CORE		4

#define EM_386 3
#define EV_CURRENT 1

#define PT_NULL		0
#define PT_LOAD		1
#define PT_DYNAMIC	2
#define PT_INTERP	3
#define PT_NOTE		4
#define PT_SHLIB	5
#define PT_PHDR		6

#define SHT_NULL 	0
#define SHT_PROGBITS 	1
#define SHT_SYMTAB 	2
#define SHT_STRTAB 	3
#define SHT_RELA 	4
#define SHT_HASH 	5
#define SHT_DYNAMIC 	6
#define SHT_NOTE 	7
#define SHT_NOBITS 	8
#define SHT_REL 	9
#define SHT_SHLIB 	10
#define SHT_DYNSYM 	11


#define SHF_WRITE 0x1
#define SHF_ALLOC 0x2
#define SHF_EXECINSTR 0x4

#define STB_LOCAL	0
#define STB_GLOBAL	1
#define STB_WEAK	2

#define STT_NOTYPE	0
#define STT_OBJECT	1
#define STT_FUNC	2
#define STT_SECTION	3
#define STT_FILE	4

#define DT_NULL			0
#define DT_NEEDED		1
#define DT_PLTRELSZ		2
#define DT_PLTGOT		3
#define DT_HASH			4
#define DT_STRTAB		5
#define DT_SYMTAB		6
#define DT_RELA			7
#define DT_RELASZ		8
#define DT_RELAENT		9
#define DT_STRSZ		10
#define DT_SYMENT		11
#define DT_INIT			12
#define DT_FINI			13
#define DT_SONAME		14
#define DT_RPATH 		15
#define DT_SYMBOLIC		16
#define DT_REL			17
#define DT_RELSZ		18
#define DT_RELENT		19
#define DT_PLTREL		20
#define DT_DEBUG		21
#define DT_TEXTREL		22
#define DT_JMPREL		23
#define DT_NUM			24
#define DT_LOPROC		0x70000000
#define DT_HIPROC		0x7fffffff

#define	ELFCLASS32	1
#define ELFDATA2LSB	1
#define ET_EXEC		2
#define EM_386   	3

#define SHT_NULL	0
#define SHT_SYMTAB	2
#define SHT_RELA	4
#define SHT_NOBITS	8
#define SHT_REL		9
#define SHT_DYNSYM	11

#define R_386_32	1
#define R_386_PC32	2

#define SHN_UNDEF	0
#define SHN_COMMON	0xFFF2

#define EI_MAG0		0
#define EI_MAG1		1
#define EI_MAG2		2
#define EI_MAG3		3
#define EI_CLASS	4
#define EI_DATA		5

#define EI_NIDENT	16

#define ELFMAG0		0x7f
#define ELFMAG1		'E'
#define ELFMAG2		'L'
#define ELFMAG3		'F'

typedef struct {
    uchar e_ident[EI_NIDENT];
    uint16_t e_type;
    uint16_t e_machine;
    uint32_t e_version;
    uint32_t e_entry;		/* Entry point */
    uint32_t e_phoff;
    uint32_t e_shoff;
    uint32_t e_flags;
    uint16_t e_ehsize;
    uint16_t e_phentsize;
    uint16_t e_phnum;
    uint16_t e_shentsize;
    uint16_t e_shnum;
    uint16_t e_shstrndx;
} elf_file_t;

typedef struct {
    uint32_t p_type;
    uint32_t p_offset;
    uint32_t p_vaddr;
    uint32_t p_paddr;
    uint32_t p_filesz;
    uint32_t p_memsz;
    uint32_t p_flags;
    uint32_t p_align;
} elf_phdr_t;

typedef struct {
    uint32_t sh_name;
    uint32_t sh_type;		/* Type of section */
    uint32_t sh_flags;		/* Miscellaneous section attributes */
    uint32_t sh_addr;		/* Section virtual addr at execution */
    uint32_t sh_offset;		/* Section file offset */
    uint32_t sh_size;		/* Size of section in uchars */
    uint32_t sh_link;		/* Index of another section */
    uint32_t sh_info;		/* Additional section information */
    uint32_t sh_addralign;	/* Section alignment */
    uint32_t sh_entsize;	/* Entry size if section holds table */
} elf_shdr_t;

typedef struct {
    uint32_t st_name;
    uint32_t st_value;
    uint32_t st_size;
    uchar st_info;
    uchar st_other;
    uint16_t st_shndx;
} elf_syminfo_t;

typedef struct {
    uint32_t r_offset;
    uint32_t r_info;
} elf_relinfo_t;

typedef struct elf_rela_info {
    uint32_t r_offset;
    uint32_t r_info;
    uint32_t r_addend;
} elf_relainfo_t;

typedef struct {
    uint32_t adr __PACKED__;
    uchar type __PACKED__;
    uint32_t symtab_index:24 __PACKED__;
    uint32_t addend __PACKED__;
} elf_reloc_t;

#endif	/* __ELF_H__ */
